package point;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import environment.Simulation;
import force.CenterMass;
import force.ForceVector;
import force.Gravity;
import force.Viscosity;
import force.WallRepulsion;
/**
 * Abstract class that encompasses all general behaviors of Points (masses).
 * @author Xi Du, Michael Deng
 *
 */
public abstract class ObjectPoint {
    /**
     * @param WIDTH_OF_POINT = 16
     */
    private static final int WIDTH_OF_POINT = 16;
    /**
     * @param myCenter center
     */
    private Point2D myCenter;
    /**
     * @param mySize size
     */
    private Dimension mySize;
    /**
     * @param myID ID
     */
    private int myID;
    /**
     * @param myMass the mass of the point
     */
    private double myMass;
    /**
     * @param myAcceleration the acceleration of the point
     */
    private ForceVector myAcceleration;

/**
 * @param id ID
 * @param x location
 * @param y location
 * @param mass mass
 */
    public ObjectPoint(final int id, final double x,
            final double y, final double mass) {
        myAcceleration = new ForceVector();
        myMass = mass;
        myID = id;
        setCenter(x, y);
        mySize = new Dimension(WIDTH_OF_POINT, WIDTH_OF_POINT);
    }

    /**
     * @param pen graphic
     */
    public final void paint(final Graphics2D pen) {
        pen.setColor(Color.BLACK);
        pen.fillOval(getLeft(), getTop(), getSize().width, getSize().height);
    }

/**
 * @param canvas container
 * @param dt time
 */
    public abstract void update(Simulation canvas, double dt);

/**
 * @param id given ID
 * @return if the given ID is the same
 */
    public final boolean match(final int id) {
        return myID == id;
    }

/**
 * @param f force
 */
    public abstract void applyForce(ForceVector f);



    /**
     * @return Returns shape's center.
     */
    public final Point2D getCenter() {
        return myCenter;
    }

    /**
     * Resets shape's center.
     * @param x location x
     * @param y location y
     */
    public final void setCenter(final double x, final double y) {
        myCenter = new Point2D.Double(x, y);
    }

    /**
     * @return Returns shape's left-most coordinate.
     */
    public final int getLeft() {
        return (int) (getCenter().getX() - getSize().width / 2);
    }

    /**
     * @return Returns shape's top-most coordinate.
     */
    public final int getTop() {
        return (int) (getCenter().getY() - getSize().height / 2);
    }

    /**
     * @return Returns shape's right-most coordinate.
     */
    public final int getRight() {
        return (int) (getCenter().getX() + getSize().width / 2);
    }

    /**
     * Reports shape's bottom-most coordinate.
     * @return bottom-most coordinate
     */
    public final int getBottom() {
        return (int) (getCenter().getY() + getSize().height / 2);
    }

    /**
     * @return Returns shape's size.
     */
    public final Dimension getSize() {
        return mySize;
    }


    /**
     * @return myID
     */
    public final int getID() {
        return myID;
    }
    /**
     * @return myMass
     */
    public final double getMass() {
        return myMass;
    }
    /**
     * @return myAcceleration
     */
    public final ForceVector getAccel() {
        return myAcceleration;
    }
/**
 * 
 * @param g abstract class set gravity
 */
    public abstract void setGravity(Gravity g);
    /**
     * 
     * @param v abstract class set viscosity force
     */
    public abstract void setViscosity(Viscosity v);
    /**
     * 
     * @param c abstract class set Centermass
     */
    public abstract void setCentermass(CenterMass c);
    /**
     * 
     * @param w abstract class set Wallrepulsion
     */
    public abstract void setWallrepulsion(WallRepulsion w);

}
